package com.guodi.model.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guodi.common.utils.DateUtil;
import com.guodi.common.utils.PageData;
import com.guodi.map.entity.MapDivision;
import com.guodi.map.feign.IMapClient;
import com.guodi.model.constant.IdtIndicatorsConst;
import com.guodi.model.constant.ModelConst;
import com.guodi.model.dto.IdtIndicatorsRelTree;
import com.guodi.model.entity.*;
import com.guodi.model.feign.ISysClientFeign;
import com.guodi.model.mapper.IdtIndicatorsMapper;
import com.guodi.model.service.*;
import com.guodi.model.utils.ConvertUtil;
import com.guodi.model.utils.RegularUtils;
import com.guodi.model.utils.TimeUtils;
import com.guodi.system.feign.IDictClient;
import com.guodi.system.feign.ISysClient;
import com.guodi.system.vo.DictVO;
import com.guodi.system.vo.OrgVO;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import javax.annotation.Resource;

import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.lang.reflect.Method;
import java.util.*;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


/**
 * @描述：指标接口实现类
 * @作者: 彭辉
 * @日期: 2020-06-05
 */
@Service
public class IdtIndicatorsServiceImpl extends ServiceImpl<IdtIndicatorsMapper, IdtIndicators> implements IIdtIndicatorsService {
    @Resource
    private IIdtYearRelevanceService iIdtYearRelevanceService;

    @Resource
    private IIdtTargetValueService iIdtTargetValueService;

    @Resource
    private IIdtReportFillService iIdtReportFillService;

    @Resource
    private IIdtMonitorFillService iIdtMonitorFillService;

    @Resource
    private IIdtIndicatorsDirService idtIndicatorsDirService;

    @Resource
    private IIdtReportValueService iIdtReportValueService;

    @Resource
    private IIdtMonitorValueService iIdtMonitorValueService;

    @Resource
    private IdtIndicatorsMapper idtIndicatorsMapper;

    @Resource
    private IMdlModelService iMdlModelService;

    @Resource
    private IDictClient dictBizClient;

    @Resource
    private ISysClient sysClient;

    @Resource
    private ISysClientFeign sysClientFeign;

    @Resource
    private IMapClient iMapClient;

    @Resource
    private IIdtWarnRuleService iIdtWarnRuleService;
    /**
     * 指标数据来源 formula
     */
    private static final String IDT_DATASOURCE_FORMULA = "formula";

    /**
     * 删除指标，会级联删除指标上报值、监测值、目标值、对标关系、上报值填报记录、监测值填报记录
     *
     * @入参： indicatorIds 指标id列表
     * @出参： 删除指标数
     * @作者: 陈宏成
     * @日期: 2021/02/07 11:23
     */
    @Override
    @Transactional
    public int deleteIndicatorByIds(List<String> indicatorIds) {
        // 删除指标
        int num = idtIndicatorsMapper.deleteBatchIds(indicatorIds);
        // 删除指标上报值
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.in("indicators_id", indicatorIds);
        this.iIdtReportValueService.remove(queryWrapper);
        // 删除指标监测值
        queryWrapper = new QueryWrapper();
        queryWrapper.in("indicators_id", indicatorIds);
        this.iIdtMonitorValueService.remove(queryWrapper);
        // 删除指标对标关系
        queryWrapper = new QueryWrapper();
        queryWrapper.in("indicators_id", indicatorIds);
        this.iIdtYearRelevanceService.remove(queryWrapper);
        // 删除指标目标值
        queryWrapper = new QueryWrapper();
        queryWrapper.in("indicators_id", indicatorIds);
        this.iIdtTargetValueService.remove(queryWrapper);
        // 删除指标上报值填报记录
        queryWrapper = new QueryWrapper();
        queryWrapper.in("indicators_id", indicatorIds);
        this.iIdtReportFillService.remove(queryWrapper);
        // 删除指标监测值填报记录
        queryWrapper = new QueryWrapper();
        queryWrapper.in("indicators_id", indicatorIds);
        this.iIdtMonitorFillService.remove(queryWrapper);
        // 删除指标目录记录
        queryWrapper = new QueryWrapper();
        queryWrapper.in("indicators_id", indicatorIds);
        queryWrapper.in("type", 2);
        this.idtIndicatorsDirService.remove(queryWrapper);

        return num;
    }

    @Override
    public void updateStatus(String indicatorsId) {
        String[] indicatorsIds = indicatorsId.split(",");
        QueryWrapper<IdtIndicators> queryWrapper = new QueryWrapper<>();
        // queryWrapper.eq("datasource","hand");
        // queryWrapper.eq("update_type",1);
        queryWrapper.in("id", indicatorsIds);
        List<IdtIndicators> idtIndicatorsList = this.list(queryWrapper);
        //更新状态
        for (IdtIndicators indicators : idtIndicatorsList) {
            List<IdtMonitorValue> idtMonitorValues = iIdtMonitorValueService.getNewestData(indicators.getId());
            if (indicators.getUpdateCycle().equals("year")) {
                if (idtMonitorValues.size() > 0) {
                    Optional<IdtMonitorValue> optional = idtMonitorValues.stream().filter(x -> StringUtils.isNotBlank(x.getMonitorTime())
                            && x.getMonitorTime().equals(TimeUtils.getPreYear())).findFirst();
                    if (optional.isPresent()) {
                        // 设置已更新
                        indicators.setUpdateStatus("0");
                        indicators.setUpdateTime(null);
                    } else {
                        indicators.setUpdateStatus(TimeUtils.getUpdateStatus("year"));
                        indicators.setUpdateTime(TimeUtils.getPreYear());
                    }
                } else {
                    indicators.setUpdateStatus(TimeUtils.getUpdateStatus("year"));
                    indicators.setUpdateTime(TimeUtils.getPreYear());
                }
            } else if (indicators.getUpdateCycle().equals("month")) {
                if (idtMonitorValues.size() > 0) {
                    Optional<IdtMonitorValue> optional = idtMonitorValues.stream().filter(x -> StringUtils.isNotBlank(x.getMonitorTime())
                            && x.getMonitorTime().equals(TimeUtils.getPreMonth())).findFirst();
                    if (optional.isPresent()) {
                        // 设置已更新
                        indicators.setUpdateStatus("0");
                        indicators.setUpdateTime(null);
                    } else {
                        indicators.setUpdateStatus(TimeUtils.getUpdateStatus("month"));
                        indicators.setUpdateTime(TimeUtils.getPreMonth());
                    }
                } else {
                    indicators.setUpdateStatus(TimeUtils.getUpdateStatus("month"));
                    indicators.setUpdateTime(TimeUtils.getPreMonth());
                }
            } else {
                if (idtMonitorValues.size() > 0) {
                    Optional<IdtMonitorValue> optional = idtMonitorValues.stream().filter(x -> StringUtils.isNotBlank(x.getMonitorTime())
                            && x.getMonitorTime().equals(TimeUtils.getPreQuarter())).findFirst();
                    if (optional.isPresent()) {
                        // 设置已更新
                        indicators.setUpdateStatus("0");
                        indicators.setUpdateTime(null);
                    } else {
                        indicators.setUpdateStatus(TimeUtils.getUpdateStatus("quarter"));
                        indicators.setUpdateTime(TimeUtils.getPreQuarter());
                    }
                } else {
                    indicators.setUpdateStatus(TimeUtils.getUpdateStatus("quarter"));
                    indicators.setUpdateTime(TimeUtils.getPreQuarter());
                }
            }
        }
        // 更新数据库
        if (idtIndicatorsList.size() > 0) {
            this.updateBatchById(idtIndicatorsList);
        }
    }

    @Override
    public List<IdtIndicators> updateReportStatus(String indicatorsId) {
        String[] indicatorsIds = indicatorsId.split(",");
        // 根据传入的id 获取指标总览模块下所有指标数据
        QueryWrapper<IdtIndicators> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", indicatorsIds);
        List<IdtIndicators> idtIndicatorsList = this.list(queryWrapper);
        // 存储状态更新后的指标
        List<IdtIndicators> updateList = new ArrayList<>();
        //更新状态
        for (IdtIndicators indicators : idtIndicatorsList) {
            List<IdtReportValue> idtReportValues = iIdtReportValueService.getNewestData(indicators.getId());
            // 上报值统一按照年度更新
            if (idtReportValues.size() > 0) {
                Optional<IdtReportValue> optional = idtReportValues.stream().filter(x -> (x.getYear() != null)
                        && x.getYear().toString().equals(TimeUtils.getPreYear())).findFirst();
                if (optional.isPresent()) {
                    indicators.setUpdateReportStatus("0");
                    indicators.setUpdateReportTime(null);
                    updateList.add(indicators);
                } else {
                    indicators.setUpdateReportStatus(TimeUtils.getReportStatus("year"));
                    indicators.setUpdateReportTime(TimeUtils.getPreYear());
                }
            } else {
                indicators.setUpdateReportStatus(TimeUtils.getReportStatus("year"));
                indicators.setUpdateReportTime(TimeUtils.getPreYear());
            }
        }
        // 更新数据库
        if (idtIndicatorsList.size() > 0) {
            this.updateBatchById(idtIndicatorsList);
        }
        return updateList;
    }

    @Override
    public void updateSortStatus(List<String> ids, String userId, Integer sortStatus) {
        List<IdtIndicators> idtIndicatorsList = new ArrayList<>();
        for (String id : ids) {
            IdtIndicators idtIndicators = new IdtIndicators();
            idtIndicators.setId(id);
            idtIndicators.setSortStatus(sortStatus);
            idtIndicators.setModifyTime(new Date());
            idtIndicators.setModifier(userId);
            idtIndicatorsList.add(idtIndicators);
        }
        this.updateBatchById(idtIndicatorsList);
    }

    @Override
    public List<IdtIndicators> listByCode(String code) {
        return idtIndicatorsMapper.listByCode(code);
    }

    @Override
    public List<String> listEntityByCode(List<String> codes) {
        QueryWrapper<IdtIndicators> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("code", codes);
        List<IdtIndicators> idtIndicatorsList = this.list(queryWrapper);
        if (idtIndicatorsList.size() > 0) {
            List<String> ids = idtIndicatorsList.stream().map(x -> x.getId()).collect(Collectors.toList());
            return ids;
        }
        return new ArrayList<>();
    }

    @Override
    public String[] listInIndicatorsIds(String indicatorsId) {
        //存储所有指标ID
        List<String> resultList = new ArrayList<>();
        String[] indicatorsIds = indicatorsId.split(",");
        for (int i = 0; i < indicatorsIds.length; i++) {
            resultList.add(indicatorsIds[i]);
            IdtIndicators idtIndicators = this.getById(indicatorsIds[i]);
            if (StringUtils.isNotBlank(idtIndicators.getDatasource()) && idtIndicators.getDatasource().equals("formula")) {
                if (StringUtils.isNotBlank(idtIndicators.getCalculateResult())) {
                    List<String> codes = RegularUtils.extractString(idtIndicators.getCalculateResult());
                    List<String> ids = this.listEntityByCode(codes);
                    resultList.addAll(ids);
                }
            }
        }
        List<String> myList = resultList.stream().distinct().collect(Collectors.toList());
        return myList.toArray(new String[myList.size()]);
    }

    /**
     * @描述: 获取指标树状图
     * @入参:
     * @出参:
     * @作者: 汤厚韬
     * @日期: 2020/12/29
     **/
    @Override
    public List<IdtIndicatorsRelTree> getIdtIndicatorsTree(String dirId, String name) {
        // 获取数据库指标项列表，获取未关联的指标项
        QueryWrapper<IdtIndicators> wrapper = new QueryWrapper();
        wrapper.notInSql("id", "select indicators_id from idt_indicators_dir where parent_id = '" + dirId + "' and type = 2");
        if (StringUtils.isNotBlank(name)) {
            wrapper.and(i -> i.like("name", name).or().like("code", name));
        }
        List<IdtIndicators> dbList = this.list(wrapper);
        List<IdtIndicatorsRelTree> resultList = new ArrayList<>();
        if (dictBizClient.getList(IdtIndicatorsConst.DICT_INDICATORS_TYPE) != null && dictBizClient.getList(IdtIndicatorsConst.DICT_INDICATORS_TYPE).getCode() == 200) {
            Map<String, IdtIndicatorsRelTree> tempMap = new HashMap<>();
            // 获取指标类型字典
            List<DictVO> dictBizListList = dictBizClient.getList(IdtIndicatorsConst.DICT_INDICATORS_TYPE).getData();
            for (int i = 0; i < dictBizListList.size(); i++) {
                DictVO dictBiz = dictBizListList.get(i);
                // 设置指标类型节点
                IdtIndicatorsRelTree idtIndicatorsRelTree = new IdtIndicatorsRelTree();
                idtIndicatorsRelTree.setId(String.valueOf(i));
                idtIndicatorsRelTree.setCode(dictBiz.getDictKey());
                idtIndicatorsRelTree.setName(dictBiz.getDictValue());
                List<IdtIndicatorsRelTree> tList = new ArrayList<>();
                idtIndicatorsRelTree.setChildList(tList);
                tempMap.put(dictBiz.getDictKey(), idtIndicatorsRelTree);
                resultList.add(idtIndicatorsRelTree);
            }
            for (IdtIndicators idtIndicators : dbList) {
                // 设置指标项节点
                IdtIndicatorsRelTree tree = new IdtIndicatorsRelTree();
                tree.setId(idtIndicators.getId());
                tree.setName(idtIndicators.getName());
                tree.setCode(idtIndicators.getCode());
                tree.setType(idtIndicators.getType());
                tree.setUnit(idtIndicators.getUnit());
                if (tempMap.get(idtIndicators.getType()) != null) {
                    // 设置指标项父节点指标类型
                    tree.setPid(tempMap.get(idtIndicators.getType()).getId());
                    tempMap.get(idtIndicators.getType()).getChildList().add(tree);
                } else {
                    resultList.add(tree);
                }
            }
            Iterator<IdtIndicatorsRelTree> iterator = resultList.iterator();
            while (iterator.hasNext()) {
                IdtIndicatorsRelTree idtDir = iterator.next();
                if (idtDir.getChildList() == null || idtDir.getChildList().size() <= 0) {
                    iterator.remove();
                }
            }
        }
        return resultList;
    }

    /**
     * @描述:获取新增指标项编码
     * @入参:
     * @出参:
     * @作者: 汤厚韬
     * @日期: 2021/1/21
     **/
    @Override
    public String getAddIdtIndicatorsCode() {
        String year = DateUtil.getYear();
        String addNum = "";
        LambdaQueryWrapper<IdtIndicators> lambda = new QueryWrapper().lambda();
        lambda.like(IdtIndicators::getCode, year);
        lambda.orderByDesc(IdtIndicators::getCode);
        List<IdtIndicators> list = super.list(lambda);
        if (list != null && list.size() > 0) {
            String num = list.get(0).getCode().replace(year, "");
            addNum = String.format("%03d", Integer.valueOf(num) + 1);
        } else {
            addNum = "001";
        }
        return (year + addNum);
    }

    /**
     * @描述: 获取单位名称集合
     * @入参:
     * @出参:
     * @作者: 汤厚韬
     * @日期: 2021/1/25 16:50
     **/
    @Override
    public Map<String, String> getDeptNameMap() {
        // 获取所有子单位，基础运维未提供
        List<OrgVO> allList = sysClient.getOrgChild(0L).getData();
//        List<OrgVO> allList = sysClientFeign.deptList(null, false).getData();
        Map<String, String> deptMap = new HashMap<>();
        for (OrgVO temp : allList) {
            deptMap.put(temp.getId().toString(), temp.getOrgName());
        }
        return deptMap;
    }

    /**
     * @描述: 获取单位名称集合
     * @入参:
     * @出参:
     * @作者: 汤厚韬
     * @日期: 2021/1/25 16:50
     **/
    @Override
    public Map<String, String> getDeptIdMap() {
        // 获取所有子单位，基础运维未提供
        //List<OrgVO> allList = sysClient.getOrgChild(0L).getData();
        List<OrgVO> allList = sysClientFeign.deptList(null, false).getData();
        Map<String, String> deptMap = new HashMap<>();
        for (OrgVO temp : allList) {
            deptMap.put(temp.getOrgName(), temp.getId().toString());
        }
        return deptMap;
    }

    /**
     * @param deptIds
     * @描述: 获取单位名称字符串
     * @入参:
     * @出参:
     * @作者: 汤厚韬
     * @日期: 2021/1/25 16:50
     */
    @Override
    public String getDeptNameStr(String deptIds, Map<String, String> deptMap) {
        if (StringUtils.isBlank(deptIds)) {
            return "";
        }
        String[] ids = deptIds.split(",");
        String name = "";
        for (String id : ids) {
            if (deptMap.get(id) != null) {
                name += deptMap.get(id) + ",";
            }
        }
        if (StringUtils.isNotBlank(name)) {
            name = name.substring(0, name.length() - 1);
        }
        return name;
    }

    /**
     * @描述: 计算差值 正向指标：监测值-规划值，反向指标：规划值-监测值
     * @入参:
     * @出参:
     * @作者: 汤厚韬
     * @日期: 2021/1/7
     **/
    public Double countDiffValue(String warnName, String targetValue, String monitorValue) {
        // 差值计算，数值缺一则返回null，前端置为-- 20210818
        if (StringUtils.isBlank(targetValue) || StringUtils.isBlank(monitorValue)) {
            return null;
        }
        Double diffValue = null;
        if ("正向".equals(warnName)) {
            Double val = Double.parseDouble(monitorValue) - Double.parseDouble(targetValue);
            diffValue = ConvertUtil.formatNum(val, 2);
        } else if ("反向".equals(warnName)) {
            Double val = Double.parseDouble(targetValue) - Double.parseDouble(monitorValue);
            diffValue = ConvertUtil.formatNum(val, 2);
        }
        return Double.valueOf(diffValue);
    }

    /**
     * @描述: 解析模型结果数据
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2021/7/6 11:01
     **/
    @Override
    public List<Map<String, String>> analysisModelResult(List<MdlModelResult> mdlModelResults, IdtIndicators idtIndicators) {
        // 定义返回解析数据集
        List<Map<String, String>> mapResult = new ArrayList<>();
        // 根据模型选择模型结果结构，目前仅包含两种格式矢量、栅格
        // Feature 格式 ：{"GroupFieldName":"行政区;地类","RootGroupItem":{"GroupItemCode":"441203","GroupItemName":"河南省","GroupItemLevelName":"行政区","StatisticInformation":{"Current":{"$合计$":{"Area_Value":"120398.818483979","Area_Unit":"公顷","Count":"30407"},"1":{"Area_Value":"100976.945256248","Area_Unit":"公顷","Count":"18745"},"2":{"Area_Value":"9913.5899269271","Area_Unit":"公顷","Count":"5629"}}},"SubLevel1GroupItems":[{"GroupItemCode":"4106","GroupItemName":"鹤壁市","GroupItemLevelName":"行政区","StatisticInformation":{"Current":{"$合计$":{"Area_Value":"120398.818483979","Area_Unit":"公顷","Count":"30407"},"1":{"Area_Value":"100976.945256248","Area_Unit":"公顷","Count":"18745"},"2":{"Area_Value":"9913.5899269271","Area_Unit":"公顷","Count":"5629"}}},"SubLevel1GroupItems":[{"GroupItemCode":"410603","GroupItemName":"山城区","GroupItemLevelName":"行政区","StatisticInformation":{"Current":{"$合计$":{"Area_Value":"330.115080397084","Area_Unit":"公顷","Count":"5"},"1":{"Area_Value":"33.6037205055143","Area_Unit":"公顷","Count":"2"},"2":{"Area_Value":"16.2078076325987","Area_Unit":"公顷","Count":"1"}}},"SubLevel1GroupItems":[]}]}]}}
        // Raster  格式 ：{"GroupFieldName":"行政区;地类","RootGroupItem":{"GroupItemCode":"441203","GroupItemName":"河南省","GroupItemLevelName":"行政区","StatisticInformation":{"Warn":[{"Name":"不超载","Area":"21388455000","Percent":"100.00%"},{"Name":"临界超载","Area":"0","Percent":"0.00%"},{"Name":"超载","Area":"0","Percent":"0.00%"}]},"SubLevel1GroupItems":[{"GroupItemCode":"4106","GroupItemName":"鹤壁市","GroupItemLevelName":"行政区","StatisticInformation":{"Warn":[{"Name":"不超载","Area":"2138845500","Percent":"100.00%"},{"Name":"临界超载","Area":"0","Percent":"0.00%"},{"Name":"超载","Area":"0","Percent":"0.00%"}]},"SubLevel1GroupItems":[{"GroupItemCode":"410603","GroupItemName":"山城区","GroupItemLevelName":"行政区","StatisticInformation":{"Warn":[{"Name":"不超载","Area":"136090800","Percent":"100.00%"},{"Name":"临界超载","Area":"0","Percent":"0.00%"},{"Name":"超载","Area":"0","Percent":"0.00%"}]},"SubLevel1GroupItems":[]}]}]}}
        MdlModel model = iMdlModelService.getById(idtIndicators.getModelId());
        if (model.getType().equals(ModelConst.MODEL_TYPE_FEATURE)) {
            // 解析矢量数据
            for (MdlModelResult mdlModelResult : mdlModelResults) {
                try {
                    JSONObject resultJson = JSONObject.fromObject(mdlModelResult.getResult());
                    JSONObject jsonData = resultJson.getJSONObject(ModelConst.MODEL_LEVEL_ROOTGROUPITEM).getJSONObject(ModelConst.MODEL_STATISTICAL_STATISTICINFORMATION).getJSONObject(ModelConst.MODEL_VALUE_TYPE_CURRENT);
                    if (!jsonData.containsKey(idtIndicators.getModelKeyField())) {
                        continue;
                    }
                    // 解析省数据
                    String mValue = jsonData.getJSONObject(idtIndicators.getModelKeyField()).getString(idtIndicators.getModelValueField());
                    String dCode = resultJson.getJSONObject(ModelConst.MODEL_LEVEL_ROOTGROUPITEM).getString(ModelConst.MODEL_FEATURE_DIVISION_GROUPITEMCODE);
                    Map map = new HashMap();
                    map.put("mValue", mValue);
                    map.put("dCode", dCode);
                    map.put("year", mdlModelResult.getYear());
                    mapResult.add(map);
                    // 获取模型结果各个市的数据集合
                    JSONArray resultArray = resultJson.getJSONObject(ModelConst.MODEL_LEVEL_ROOTGROUPITEM).getJSONArray(ModelConst.MODEL_LEVEL_SUBLEVEL1GROUPITEM);
                    // 获取模型结果各个的数据集合
                    recursionJson(resultArray, mdlModelResult, mapResult, idtIndicators);
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
            }
            return mapResult;
        } else if (model.getType().equals(ModelConst.MODEL_TYPE_RASTER)) {
            // 解析栅格数据
            for (MdlModelResult mdlModelResult : mdlModelResults) {
                try {
                    JSONObject resultJson = JSONObject.fromObject(mdlModelResult.getResult());
                    recursionRasterJson(resultJson, mdlModelResult, mapResult, idtIndicators);
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
            }
            return mapResult;
        } else {
            return null;
        }
    }

    public List<Map<String, String>> recursionJson(JSONArray jsonArray, MdlModelResult mdlModelResult, List<Map<String, String>> mapResult, IdtIndicators idtIndicators) {
        // 递归遍历获取到对应行政区划下的数据
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject resultObject = jsonArray.getJSONObject(i);
            if (!resultObject.getJSONObject(ModelConst.MODEL_STATISTICAL_STATISTICINFORMATION).isEmpty()) {
                if (resultObject.getJSONObject(ModelConst.MODEL_STATISTICAL_STATISTICINFORMATION).getJSONObject(ModelConst.MODEL_VALUE_TYPE_CURRENT).getJSONObject(idtIndicators.getModelKeyField()) != null) {
                    JSONObject jsonData = resultObject.getJSONObject(ModelConst.MODEL_STATISTICAL_STATISTICINFORMATION).getJSONObject(ModelConst.MODEL_VALUE_TYPE_CURRENT);
                    if (!jsonData.containsKey(idtIndicators.getModelKeyField())) {
                        continue;
                    }
                    String mValue = jsonData.getJSONObject(idtIndicators.getModelKeyField()).getString(idtIndicators.getModelValueField());
                    String dCode = resultObject.getString(ModelConst.MODEL_FEATURE_DIVISION_GROUPITEMCODE);
                    Map map = new HashMap();
                    map.put("mValue", mValue);
                    map.put("dCode", dCode);
                    map.put("year", mdlModelResult.getYear());
                    mapResult.add(map);
                }
            }
            recursionJson(resultObject.getJSONArray(ModelConst.MODEL_LEVEL_SUBLEVEL1GROUPITEM), mdlModelResult, mapResult, idtIndicators);
        }
        return mapResult;
    }

    public List<Map<String, String>> recursionRasterJson(JSONObject jsonObject, MdlModelResult mdlModelResult, List<Map<String, String>> mapResult, IdtIndicators idtIndicators) {
        // 解析数据
        if (!jsonObject.getJSONObject(ModelConst.MODEL_STATISTICAL_STATISTICINFORMATION).isEmpty()) {
            if (jsonObject.getJSONObject(ModelConst.MODEL_STATISTICAL_STATISTICINFORMATION).getJSONArray(ModelConst.MODEL_STATISTICAL_EVALUATION) != null) {
                JSONArray jsonArray = jsonObject.getJSONObject(ModelConst.MODEL_STATISTICAL_STATISTICINFORMATION).getJSONArray(ModelConst.MODEL_STATISTICAL_EVALUATION);
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject resultObject = jsonArray.getJSONObject(i);
                    if (resultObject.getString(ModelConst.MODEL_RASTER_FIELD_NAME).equals(idtIndicators.getModelKeyField())) {
                        String mValue = resultObject.getString(idtIndicators.getModelValueField());
                        String dCode = jsonObject.getString(ModelConst.MODEL_STATISTICAL_AREACODE);
                        Map map = new HashMap();
                        map.put("mValue", mValue);
                        map.put("dCode", dCode);
                        map.put("year", mdlModelResult.getYear());
                        mapResult.add(map);
                    }
                }
            }
        }
        // 递归下级数据
        JSONArray array = jsonObject.getJSONArray(ModelConst.MODEL_STATISTICAL_SUBRASTERMODELS);
        for (int i = 0; i < array.size(); i++) {
            recursionRasterJson(array.getJSONObject(i), mdlModelResult, mapResult, idtIndicators);
        }
        return mapResult;
    }

    /**
     * @描述: 更新指标预警状态
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2021/8/4 11:22
     **/
    @Override
    public String updateWarnStatus(ApiIndicatorsVal apiIndicatorsVal) {
        // 定义返回结果
        String result = "null,所有公式均不符合";
        try {
            // 指标预警规则一共5种：监测值、基期值、规划值、平均监测值、上一监测值
            if (StringUtils.isNotBlank(apiIndicatorsVal.getWarnRuleConfig())) {
                // 如果该指标预警规则不为空，则更新指标预警状态
                String jsonObject = apiIndicatorsVal.getWarnRuleConfig();
                List<IdtWarnRuleValue> idtWarnRuleValues = com.alibaba.fastjson.JSONArray.parseArray(jsonObject, IdtWarnRuleValue.class);
                // 1.产品要求反向计算
                for (int i = idtWarnRuleValues.size() - 1; i >= 0; i--) {
                    // 2.获取指标预警公式,去除公式中的转义字符\以及%
                    IdtWarnRuleValue idtWarnRuleValue = idtWarnRuleValues.get(i);
                    String warnRule = idtWarnRuleValue.getWarnRule().replaceAll("//", "").replaceAll("%", "");
                    if (!StringUtils.isNotBlank(warnRule)) {
                        result = "null,尚未配置规则";
                        return result;
                    }
                    // 3.验证该公式中是否包含不存在的值，如有则给出提示，退出循环
                    List<String> list = new ArrayList<String>();
                    Matcher m = Pattern.compile("\\\"(.*?)\\\"").matcher(warnRule);
                    while (m.find()) {
                        list.add(m.group().replace("\"", ""));
                    }
                    // 去重
                    List<String> newList = list.stream().distinct().collect(Collectors.toList());
                    // 动态验证公式数值是否存在或者不为空
                    String calculationFormula = warnRule.replace("\"", "");
                    ScriptEngineManager manager = new ScriptEngineManager();
                    ScriptEngine engine = manager.getEngineByName("js");
                    for (String code : newList) {
                        Method mGet = apiIndicatorsVal.getClass().getMethod("get" + code);
                        String value = (String) mGet.invoke(apiIndicatorsVal);
                        if (null != value && Double.parseDouble(value) >= 0.0) {
                            engine.put(code, Double.parseDouble(value));
                            continue;
                        } else {
                            // 组装不同数值格式返回提示信息
                            if (code.equals("TargetValue")) {
                                result = "null," + "规划值为空或未配置对标";
                            } else if (code.equals("AvgMonitorValue")) {
                                result = "null," + "平均监测值为空";
                            } else if (code.equals("LastMonitorValue")) {
                                result = "null," + "上一监测值为空";
                            } else if (code.equals("MonitorValue")) {
                                result = "null," + "当前更新周期下监测值为空";
                            } else if (code.equals("BaseValue")) {
                                result = "null," + "基期值为空";
                            } else {
                                result = "null,规则配置有误";
                            }
                            return result;
                        }
                    }
                    // 4.公式数值正确，则计算公式
                    Object obectResult = engine.eval(calculationFormula);
                    if ((boolean) obectResult) {
                        // 当满足一个时，退出循环
                        result = idtWarnRuleValue.getWarnColor() + "," + idtWarnRuleValue.getWarnLevel();
                        return result;
                    }
                }
            } else {
                result = "null,尚未配置规则";
            }
        } catch (Exception e) {
            result = "null,规则配置中包含非下拉框指标值或服务异常，请检查";
            e.printStackTrace();
            return result;
        }
        return result;
    }

    /**
     * @描述: (新)查询指标数值--单指标单年份单行政区划
     * @入参: idtId 指标id
     * @入参: queryTime 查询时间字符串。
     * 如果是按年查询："2020"；如果是按季查询："2020-1"；如果是按月查询："2020-01"。
     * 不能混搭
     * @入参: divisionCode 行政区划编码
     * @入参: isFillZero 如果监测值/上报值/基期值/规划值不存在时，是否填充 0 ，true-填充，false-不填充
     * @入参: isReportValueForGrowthRatio 是否使用上报值来计算增长率。true-使用上报值计算，false-使用监测值计算
     * @出参: ApiIndicatorsVal 会查询指标的监测值、地区平均监测值、上报值、基期年、基期值、规划年、规划值、预警状态等基本数值字段
     * @作者: 陈宏成
     * @日期: 2021-08-04
     **/
    @Override
    public ApiIndicatorsVal getIdtVal(String idtId, String queryTime, String divisionCode, boolean isFillZero, boolean isReportValueForGrowthRatio) {
        if (queryTime.contains(",")) {
            throw new RuntimeException("多年份查询请使用listSingleIdtVal(String , String  , String , boolean , boolean )或者listRangeIdtVal(String idtId, String , String  , String , boolean , boolean )");
        }
        if (divisionCode.contains(",")) {
            throw new RuntimeException("多行政区划查询请使用listSingleIdtVal(String , String  , String , boolean , boolean )或者listRangeIdtVal(String idtId, String , String  , String , boolean , boolean )");
        }
        List<ApiIndicatorsVal> apiIndicatorsVals = this.listIdtVal(Arrays.asList(idtId), queryTime, divisionCode, isFillZero, isReportValueForGrowthRatio);
        return apiIndicatorsVals.isEmpty() ? null : apiIndicatorsVals.get(0);
    }

    /**
     * @描述: (新)查询指标数值，仅查询单指标多年份多行政区划
     * @入参: idtId 指标id
     * @入参: queryTimes 查询时间字符串，如果有多个，英文逗号隔开。
     * 如果是按年查询："2020,2021,2022"；如果是按季查询："2020-1,2020-2,2020-3"；如果是按月查询："2020-01,2020-02,2020-03"。
     * 不能混搭
     * @入参: divisionCodes 行政区划编码字符串，如果有多个，英文逗号隔开
     * @入参: isFillZero 如果监测值/上报值/基期值/规划值不存在时，是否填充 0 ，true-填充，false-不填充
     * @入参: isReportValueForGrowthRatio 是否使用上报值来计算增长率。true-使用上报值计算，false-使用监测值计算
     * @出参: ApiIndicatorsVal 会查询指标的监测值、地区平均监测值、上报值、基期年、基期值、规划年、规划值、预警状态等基本数值字段。 如果没有，将返回空列表
     * @作者: 陈宏成
     * @日期: 2021-08-04
     **/
    @Override
    public List<ApiIndicatorsVal> listSingleIdtVal(String idtId, String queryTimes, String divisionCodes, boolean isFillZero, boolean isReportValueForGrowthRatio) {
        List<ApiIndicatorsVal> apiIndicatorsVals = this.listIdtVal(Arrays.asList(idtId), queryTimes, divisionCodes, isFillZero, isReportValueForGrowthRatio);
        return apiIndicatorsVals;
    }

    /**
     * @描述: (新)查询指标数值，查询多指标多年份多行政区划
     * @入参: idtIds  必填，指标id列表
     * @入参: queryTimeBegin 查询时间字符串，年：2020；月：2020-01；季度：2020-1
     * @入参: queryTimeEnd 查询时间字符串，年：2020；月：2020-01；季度：2020-1
     * @入参: divisionCodes 必填，行政区划编码字符串，如果有多个，英文逗号隔开
     * @入参: isFillZero 必填，如果监测值/上报值/基期值/规划值不存在时，是否填充 0 ，true-填充，false-不填充
     * @入参: isReportValueForGrowthRatio 必填，是否使用上报值来计算增长率。true-使用上报值计算，false-使用监测值计算
     * @出参: Map-key: 指标id。Map-value: ApiIndicatorsVal 会查询指标的监测值、地区平均监测值、上报值、基期年、基期值、规划年、规划值、预警状态等基本数值字段。
     * @作者: 陈宏成
     * @日期: 2021-08-04
     **/
    @Override
    public Map<String, List<ApiIndicatorsVal>> mapIdtVal(List<String> idtIds, String queryTimeBegin, String queryTimeEnd, String divisionCodes, boolean isFillZero, boolean isReportValueForGrowthRatio) {
        // 将一个时间范围转成一个列表
        List<String> strings = DateUtil.fillTimeList(queryTimeBegin, queryTimeEnd);
        String queryTimes = String.join(",", strings);
        Map<String, List<ApiIndicatorsVal>> mapIdtVal = this.mapIdtVal(idtIds, queryTimes, divisionCodes, isFillZero, isReportValueForGrowthRatio);
        return mapIdtVal;
    }

    /**
     * @描述: (新)查询指标数值，查询多指标多年份多行政区划
     * @入参: idtIds  必填，指标id列表
     * @入参: queryTimes 查询时间字符串，如果有多个，英文逗号隔开。
     * 如果是按年查询："2020,2021,2022"；如果是按季查询："2020-1,2020-2,2020-3"；如果是按月查询："2020-01,2020-02,2020-03"。
     * 不能混搭
     * @入参: divisionCodes 必填，行政区划编码字符串，如果有多个，英文逗号隔开
     * @入参: isFillZero 必填，如果监测值/上报值/基期值/规划值不存在时，是否填充 0 ，true-填充，false-不填充
     * @入参: isReportValueForGrowthRatio 必填，是否使用上报值来计算增长率。true-使用上报值计算，false-使用监测值计算
     * @出参: Map-key: 指标id。Map-value: ApiIndicatorsVal 会查询指标的监测值、地区平均监测值、上报值、基期年、基期值、规划年、规划值、预警状态等基本数值字段。
     * @作者: 陈宏成
     * @日期: 2021-08-04
     **/
    @Override
    public Map<String, List<ApiIndicatorsVal>> mapIdtVal(List<String> idtIds, String queryTimes, String divisionCodes, boolean isFillZero, boolean isReportValueForGrowthRatio) {
        List<ApiIndicatorsVal> apiIndicatorsVals = this.listIdtVal(idtIds, queryTimes, divisionCodes, isFillZero, isReportValueForGrowthRatio);
        Map<String, List<ApiIndicatorsVal>> mapIdtVal = apiIndicatorsVals.stream().collect(Collectors.groupingBy(idtVal -> {
            return idtVal.getId();
        }));
        return mapIdtVal;
    }

    /**
     * @描述: (新)查询指标数值，仅查询单指标指定监测时间范围内多行政区划
     * @入参: idtId 指标id
     * @入参: queryTimeBegin 查询时间字符串，年：2020；月：2020-01；季度：2020-1
     * @入参: queryTimeEnd 查询时间字符串，年：2020；月：2020-01；季度：2020-1
     * @入参: divisionCodes 行政区划编码字符串，如果有多个，英文逗号隔开
     * @入参: isFillZero 如果监测值/上报值/基期值/规划值不存在时，是否填充 0 ，true-填充，false-不填充
     * @入参: isReportValueForGrowthRatio 是否使用上报值来计算增长率。true-使用上报值计算，false-使用监测值计算
     * @出参: ApiIndicatorsVal 会查询指标的监测值、地区平均监测值、上报值、基期年、基期值、规划年、规划值、预警状态等基本数值字段。 如果没有，将返回空列表
     * @作者: 陈宏成
     * @日期: 2021-08-04
     **/
    @Override
    public List<ApiIndicatorsVal> listRangeIdtVal(String idtId, String queryTimeBegin, String queryTimeEnd, String divisionCodes, boolean isFillZero, boolean isReportValueForGrowthRatio) {
        // 将一个时间范围转成一个列表
        List<String> strings = DateUtil.fillTimeList(queryTimeBegin, queryTimeEnd);
        String queryTimeStr = String.join(",", strings);
        List<ApiIndicatorsVal> apiIndicatorsValList = this.listSingleIdtVal(idtId, queryTimeStr, divisionCodes, isFillZero, isReportValueForGrowthRatio);
        return apiIndicatorsValList;
    }

    /**
     * @描述: (新)查询指标数值--多指标多监测时间多行政区划
     * 按年度查询时，如果指标更新周期是年度，那么直接取这个年度的监测值
     * 如果指标更新周期是季度/月度，那么直接取这个年度中最新的监测值，根据monitor_time进行比较
     * 按季度/月度查询时，那么直接取这个季度/月度的监测值
     * <p>
     * 仅监测值会有这种问题，上报值和规划值不需要考虑这种问题
     * @入参: idtIds  必填，指标id列表
     * @入参: queryTimes 查询时间字符串，如果有多个，英文逗号隔开。
     * 如果是按年查询："2020,2021,2022"；如果是按季查询："2020-1,2020-2,2020-3"；如果是按月查询："2020-01,2020-02,2020-03"。
     * 不能混搭
     * @入参: divisionCodes 必填，行政区划编码字符串，如果有多个，英文逗号隔开
     * @入参: isFillZero 必填，如果监测值/上报值/基期值/规划值不存在时，是否填充 0 ，true-填充，false-不填充
     * @入参: isReportValueForGrowthRatio 必填，是否使用上报值来计算增长率。true-使用上报值计算，false-使用监测值计算
     * @出参: List<ApiIndicatorsVal>会查询指标的监测值、地区平均监测值、上报值、基期年、基期值、规划年、规划值、预警状态等基本数值字段。
     * @作者: 陈宏成
     * @日期: 2021-08-04
     **/
    public List<ApiIndicatorsVal> listIdtVal(List<String> idtIds, String queryTimes, String divisionCodes, boolean isFillZero, boolean isReportValueForGrowthRatio) {
        // 前期处理
        // 查询时间处理，去除两边空格，增加一个年份列表
        String[] queryTimeArr = queryTimes.split(",");
        String[] yearArr = new String[queryTimeArr.length];
        // 扩充查询时间列表，用于查询上一年度的监测值
        HashSet<String> moreQueryTimes = new HashSet<>();
        HashSet<String> moreQueryYear = new HashSet<>();
        for (int i = 0; i < queryTimeArr.length; i++) {
            queryTimeArr[i] = queryTimeArr[i].trim();
            yearArr[i] = queryTimeArr[i].substring(0, 4);
            // 扩充
            moreQueryTimes.add(queryTimeArr[i]);
            moreQueryYear.add(yearArr[i]);
            // 获取每个查询时间的上一个时间点，主要是给监测值用
            String lastTimePoint = DateUtil.getLastTimePoint(queryTimeArr[i]);
            moreQueryTimes.add(lastTimePoint);
            moreQueryYear.add(lastTimePoint.substring(0, 4));
            // 往上取多一个年份，主要给上报值用
            moreQueryYear.add(DateUtil.getLastTimePoint(lastTimePoint.substring(0, 4)));
        }
        // 给年份排序
        Arrays.sort(queryTimeArr);
        // 行政区划处理，去除两边空格
        String[] divisionCodeArr = divisionCodes.split(",");
        for (int i = 0; i < divisionCodeArr.length; i++) {
            divisionCodeArr[i] = divisionCodeArr[i].trim();
        }

        // 查指标信息
        LambdaQueryWrapper<IdtIndicators> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.in(IdtIndicators::getId, idtIds);
        List<IdtIndicators> indicatorsList = this.list(queryWrapper1);

        // 查询监测值数据
        List<Integer> moreQueryYearIntegerList = moreQueryYear.stream().map(year -> {
            return Integer.valueOf(year);
        }).collect(Collectors.toList());
        LambdaQueryWrapper<IdtMonitorValue> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.in(IdtMonitorValue::getIndicatorsId, idtIds);
        queryWrapper2.in(IdtMonitorValue::getYear, moreQueryYearIntegerList);
        queryWrapper2.in(IdtMonitorValue::getDivisionCode, divisionCodeArr);
        List<IdtMonitorValue> monitorValueList = this.iIdtMonitorValueService.list(queryWrapper2);

        // 查询平均监测值，仅3.2版本才有
        List<IdtMonitorValue> avgMonitorValueList = this.iIdtMonitorValueService.listAvgMonitorValue(idtIds, Arrays.asList(divisionCodeArr));

        // 查询指标预警规则
        // 2021-12-29 陈宏成 因为 indicatorsList 可能为空，也就是找不到对应的指标，SQL语句in的内容为空导致报错，所以这里直接改成查询全部。
        // 预警规则 IdtWarnRule 其实已经没有啥用途了，属于历史遗留，这里暂时查询全部吧，记录数基本固定为2条的，所以问题不大。
        //Set<String> warnRuleIdSet = indicatorsList.stream().map(IdtIndicators::getWarnRuleId).collect(Collectors.toSet());
        LambdaQueryWrapper<IdtWarnRule> queryWrapper3 = new LambdaQueryWrapper<>();
        //queryWrapper3.in(IdtWarnRule::getId, warnRuleIdSet);
        List<IdtWarnRule> warnRuleList = this.iIdtWarnRuleService.list(queryWrapper3);

        // 查询上报值数据
        LambdaQueryWrapper<IdtReportValue> queryWrapper4 = new LambdaQueryWrapper<>();
        queryWrapper4.in(IdtReportValue::getIndicatorsId, idtIds);
        queryWrapper4.in(IdtReportValue::getYear, moreQueryYearIntegerList);
        queryWrapper4.in(IdtReportValue::getDivisionCode, divisionCodeArr);
        List<IdtReportValue> reportValueList = this.iIdtReportValueService.list(queryWrapper4);

        // 查询指标对标关系
        LambdaQueryWrapper<IdtYearRelevance> queryWrapper5 = new LambdaQueryWrapper<>();
        queryWrapper5.in(IdtYearRelevance::getIndicatorsId, idtIds);
        List<IdtYearRelevance> yearRelevanceList = this.iIdtYearRelevanceService.list(queryWrapper5);

        // 查询规划值数据
        LambdaQueryWrapper<IdtTargetValue> queryWrapper6 = new LambdaQueryWrapper<>();
        queryWrapper6.in(IdtTargetValue::getIndicatorsId, idtIds);
        queryWrapper6.in(IdtTargetValue::getDivisionCode, divisionCodeArr);
        List<IdtTargetValue> targetValueList = this.iIdtTargetValueService.list(queryWrapper6);

        // 行政区划，key -- 区划编码，value -- 区划名
        Map<String, String> divisionMap = iMapClient.mapDivisionCode2Name(divisionCodeArr);

        // 按指标id分组，形成map
        // 根据指标id分组
        Map<String, List<IdtIndicators>> indicatorsMap = indicatorsList.stream().collect(Collectors.groupingBy(IdtIndicators::getId));
        // 根据指标id分组
        Map<String, List<IdtMonitorValue>> monitorValueMap = monitorValueList.stream().collect(Collectors.groupingBy(IdtMonitorValue::getIndicatorsId));
        // 根据预警规则id分组
        Map<String, List<IdtWarnRule>> warnRuleMap = warnRuleList.stream().collect(Collectors.groupingBy(IdtWarnRule::getId));
        // 根据指标id分组
        Map<String, List<IdtReportValue>> reportValueMap = reportValueList.stream().collect(Collectors.groupingBy(IdtReportValue::getIndicatorsId));
        // 根据指标id分组
        Map<String, List<IdtYearRelevance>> yearRelevanceMap = yearRelevanceList.stream().collect(Collectors.groupingBy(IdtYearRelevance::getIndicatorsId));
        // 根据指标id分组
        Map<String, List<IdtTargetValue>> targetValueMap = targetValueList.stream().collect(Collectors.groupingBy(IdtTargetValue::getIndicatorsId));
        // 根据指标id和行政区划分组
        Map<String, List<IdtMonitorValue>> avgMonitorValueMap = avgMonitorValueList.stream().collect(Collectors.groupingBy(v -> {
            return v.getIndicatorsId() + "-" + v.getDivisionCode();
        }));

        // 创建返回对象
        List<LinkedList<ApiIndicatorsVal>> collect = idtIds.parallelStream().map(idtId -> {
            // 目标返回结果
            LinkedList<ApiIndicatorsVal> valLinkedList = new LinkedList<>();
            // 获取指标基本信息
            IdtIndicators idtIndicator = indicatorsMap.containsKey(idtId) ? indicatorsMap.get(idtId).get(0) : null;
            if (idtIndicator == null) {
                return null;
            }
            // 封装基本信息
            ApiIndicatorsVal baseVal = new ApiIndicatorsVal();
            baseVal.setId(idtIndicator.getId());
            baseVal.setUnit(idtIndicator.getUnit());
            baseVal.setName(idtIndicator.getName());
            baseVal.setConnotation(idtIndicator.getConnotation());
            baseVal.setAttribute(idtIndicator.getAttribute());
            baseVal.setCode(idtIndicator.getCode());
            baseVal.setGatherCompany(idtIndicator.getGatherCompany());
            baseVal.setDutyCompany(idtIndicator.getDutyCompany());
            baseVal.setDutyDepartment(idtIndicator.getDutyDepartment());
            baseVal.setCalculateUnit(idtIndicator.getCalculateUnit());
            baseVal.setUpdateCycle(idtIndicator.getUpdateCycle());
            baseVal.setWarnRuleConfig(idtIndicator.getWarnRuleConfig());
            for (String divisionCode : divisionCodeArr) {
                for (String queryTime : queryTimeArr) {
                    ApiIndicatorsVal indicatorsVal = new ApiIndicatorsVal();
                    BeanUtils.copyProperties(baseVal, indicatorsVal);
                    valLinkedList.add(indicatorsVal);

                    // 行政区划
                    indicatorsVal.setDivisionCode(divisionCode);
                    indicatorsVal.setDivisionName(divisionMap.get(divisionCode));

                    // 查询时间，查询年份
                    indicatorsVal.setQueryTime(queryTime);
                    indicatorsVal.setQueryYear(queryTime.substring(0, 4));

                    // 监测值
                    List<IdtMonitorValue> monitorValueList1 = monitorValueMap.get(idtId);
                    IdtMonitorValue lastTimeMonitorValue = null;
                    if (monitorValueList1 != null && !monitorValueList1.isEmpty()) {
                        IdtMonitorValue monitorValue1 = getMonitorValue(indicatorsVal.getId(), indicatorsVal.getDivisionCode(), indicatorsVal.getUpdateCycle(), queryTime, 2, monitorValueList1);
                        if (monitorValue1 != null) {
                            indicatorsVal.setMonitorValue(monitorValue1.getMonitorValue());
                            indicatorsVal.setMonitorYear(monitorValue1.getYear().toString());
                            indicatorsVal.setMonitorTime(monitorValue1.getMonitorTime());
                            indicatorsVal.setUpdateDate(monitorValue1.getModifyTime());
                            indicatorsVal.setWarnStatus(monitorValue1.getWarnStatus());
                            // 获取上一年的监测值
                            if (!isReportValueForGrowthRatio) {
                                // 方案一：如果这个指标是月度更新，按年查询时，取他上一个监测值也是按年取的；按月查询时，我取他上一个监测值也是按月取的
                                // String lastTimePoint = DateUtil.getLastTimePoint(queryTime);
                                // （目前使用的）方案二：如果这个指标是月度更新，不管按啥查询，都取上一个月
                                String lastTimePoint = DateUtil.getLastTimePoint(monitorValue1.getMonitorTime());

                                lastTimeMonitorValue = getMonitorValue(indicatorsVal.getId(), indicatorsVal.getDivisionCode(), indicatorsVal.getUpdateCycle(), lastTimePoint, 2, monitorValueList1);
                            }
                            // 上一监测值
                            IdtMonitorValue lastMonitorValue = this.iIdtMonitorValueService.getLastMonitorValue(idtIndicator.getId(), divisionCode, monitorValue1.getMonitorTime(), indicatorsVal.getUpdateCycle());
                            indicatorsVal.setLastMonitorValue(lastMonitorValue == null ? null : lastMonitorValue.getMonitorValue());
                        }
                    }

                    // 平均监测值
                    List<IdtMonitorValue> avg = avgMonitorValueMap.get(idtIndicator.getId() + "-" + divisionCode);
                    if (avg != null && !avg.isEmpty()) {
                        indicatorsVal.setAvgMonitorValue(avg.get(0).getMonitorValue());
                    }

                    // 上报值
                    List<IdtReportValue> idtReportValues = reportValueMap.get(idtId);
                    IdtReportValue lastTimeReportValue = null;
                    if (idtReportValues != null && !idtReportValues.isEmpty()) {
                        Optional<IdtReportValue> idtReportValueOptional = idtReportValues.stream().filter(reportValues -> {
                            // 行政区划一致 + 查询年份和上报年份一致
                            if (Objects.equals(reportValues.getDivisionCode(), divisionCode) && reportValues.getYear().intValue() == Integer.parseInt(indicatorsVal.getQueryYear())) {
                                return true;
                            }
                            return false;
                        }).findFirst();
                        if (idtReportValueOptional.isPresent()) {
                            indicatorsVal.setValue(idtReportValueOptional.get().getValue());
                            indicatorsVal.setYear(idtReportValueOptional.get().getYear().toString());
                            indicatorsVal.setIsStandard(idtReportValueOptional.get().getIsStandard());
                            indicatorsVal.setIsUnify(idtReportValueOptional.get().getIsUnify());
                            indicatorsVal.setReportExplain(idtReportValueOptional.get().getExplain());
                        }
                        if (isReportValueForGrowthRatio && idtReportValueOptional.isPresent()) {
                            // 获取上一年的上报值
                            String lastTimePoint = DateUtil.getLastTimePoint(indicatorsVal.getQueryYear());
                            idtReportValueOptional = idtReportValues.stream().filter(reportValues -> {
                                // 行政区划一致 + 查询年份和上报年份一致
                                if (Objects.equals(reportValues.getDivisionCode(), divisionCode) && reportValues.getYear().intValue() == Integer.parseInt(lastTimePoint)) {
                                    return true;
                                }
                                return false;
                            }).findFirst();
                            lastTimeReportValue = idtReportValueOptional.isPresent() ? idtReportValueOptional.get() : null;
                        }
                    }

                    // 预警规则
                    IdtWarnRule warnRule = warnRuleMap.containsKey(idtIndicator.getWarnRuleId()) ? warnRuleMap.get(idtIndicator.getWarnRuleId()).get(0) : null;
                    indicatorsVal.setWarnRule(warnRule.getName());

                    //规划值，先查对标关系，再查规划值
                    List<IdtYearRelevance> yearRelevanceList1 = yearRelevanceMap.get(idtId);
                    if (yearRelevanceList1 != null && !yearRelevanceList1.isEmpty()) {
                        Integer queryYear = Integer.valueOf(indicatorsVal.getQueryYear());
                        Optional<IdtYearRelevance> yearRelevanceOptional = yearRelevanceList1.stream().filter(yearRelevance -> {
                            Integer startYear = Integer.valueOf(yearRelevance.getMonitorReportYear().substring(0, 4));
                            Integer endYear = Integer.valueOf(yearRelevance.getMonitorReportYear().substring(5, 9));
                            if (queryYear <= endYear && queryYear >= startYear) {
                                return true;
                            }
                            return false;
                        }).findFirst();
                        if (yearRelevanceOptional.isPresent()) {
                            // 查规划值
                            List<IdtTargetValue> targetValueList1 = targetValueMap.get(idtId);
                            if (targetValueList1 != null && !targetValueList1.isEmpty()) {
                                Optional<IdtTargetValue> targetValueOptional = targetValueList1.stream().filter(targetValue -> {
                                    // 行政区划一致 + 规划值规划年和对标关系规划年一致
                                    if (Objects.equals(targetValue.getDivisionCode(), divisionCode) && targetValue.getTargetYear().intValue() == yearRelevanceOptional.get().getPlanTargetYear().intValue()) {
                                        return true;
                                    }
                                    return false;
                                }).findFirst();
                                if (targetValueOptional.isPresent()) {
                                    indicatorsVal.setBaseYear(targetValueOptional.get().getBaseYear());
                                    indicatorsVal.setBaseValue(targetValueOptional.get().getBaseValue());
                                    indicatorsVal.setTargetYear(targetValueOptional.get().getTargetYear().toString());
                                    indicatorsVal.setTargetValue(targetValueOptional.get().getTargetValue());
                                    indicatorsVal.setTargetExplain(targetValueOptional.get().getExplain());
                                }
                            }
                        }
                    }

                    // 设置差值
                    indicatorsVal.setDifferenceValue(countDiffValue(indicatorsVal.getWarnRule(), indicatorsVal.getTargetValue(), indicatorsVal.getMonitorValue()));

                    //计算完成率，只有上报值和规划值都存在且大于0，才会计算
                    // 上报值不为空 + 规划值不为空 + 上报值是数值 + 规划值是数值 + 上报值大于0 + 规划值大于0
                    if (StringUtils.isNotBlank(indicatorsVal.getValue()) && StringUtils.isNotBlank(indicatorsVal.getTargetValue())
                            && ConvertUtil.strIsNumber(indicatorsVal.getValue()) && ConvertUtil.strIsNumber(indicatorsVal.getTargetValue())
                            && Double.parseDouble(indicatorsVal.getValue()) > 0 && Double.parseDouble(indicatorsVal.getTargetValue()) > 0) {
                        Double value = Double.parseDouble(indicatorsVal.getValue());
                        Double targetValue = Double.parseDouble(indicatorsVal.getTargetValue());
                        Double completionRatio = value / targetValue * 100;
                        //保留后面两位小数
                        completionRatio = Double.parseDouble(ConvertUtil.formatNumber(completionRatio, 2));
                        //超过100按照100处理
                        completionRatio = completionRatio > 100 ? 100 : completionRatio;
                        indicatorsVal.setCompletionRatio(completionRatio);
                    } else {
                        indicatorsVal.setCompletionRatio(0.0);
                    }

                    // 获取上一年监测值和上报值
                    if (isReportValueForGrowthRatio) {
                        // 计算上报值环比率和增长率 = （当年上报值-上年上报值）/上年上报值 * 100%
                        // 条件： 上一年上报值存在 + 今年上报值存在 + 上一年上报值为数值 + 今年上报值为数值 + 上一年上报值大于0 + 今年上报值大于0
                        if (lastTimeReportValue != null && StringUtils.isNotBlank(lastTimeReportValue.getValue()) && StringUtils.isNotBlank(indicatorsVal.getValue())
                                && ConvertUtil.strIsNumber(lastTimeReportValue.getValue()) && ConvertUtil.strIsNumber(indicatorsVal.getValue())
                                && Double.parseDouble(lastTimeReportValue.getValue()) > 0 && Double.parseDouble(indicatorsVal.getValue()) > 0) {
                            Double reportValue = Double.parseDouble(indicatorsVal.getValue());
                            Double lastReportValue = Double.parseDouble(lastTimeReportValue.getValue());
                            Double ringRatio = ((reportValue - lastReportValue) / lastReportValue) * 100;
                            ringRatio = ringRatio > 100 ? 100 : ringRatio;
                            Double growthRatio = ((reportValue - lastReportValue) / lastReportValue) * 100;
                            growthRatio = growthRatio > 100 ? 100 : growthRatio;
                            //保留后面两位小数
                            ringRatio = Double.parseDouble(ConvertUtil.formatNumber(ringRatio, 2));
                            growthRatio = Double.parseDouble(ConvertUtil.formatNumber(growthRatio, 2));
                            indicatorsVal.setRingRatio(ringRatio);
                            indicatorsVal.setGrowthRatio(growthRatio);
                        } else {
                            indicatorsVal.setRingRatio(0.0);
                            indicatorsVal.setGrowthRatio(0.0);
                        }
                    } else {
                        // 计算监测值环比率和增长率 = （当年监测值-上年监测值）/上年监测值 * 100%
                        // 条件： 上一年监测值存在 + 今年监测值存在 + 上一年监测值为数值 + 今年监测值为数值 + 上一年监测值大于0 + 今年监测值大于0
                        if (lastTimeMonitorValue != null && StringUtils.isNotBlank(lastTimeMonitorValue.getMonitorValue()) && StringUtils.isNotBlank(indicatorsVal.getMonitorValue())
                                && ConvertUtil.strIsNumber(lastTimeMonitorValue.getMonitorValue()) && ConvertUtil.strIsNumber(indicatorsVal.getMonitorValue())
                                && Double.parseDouble(lastTimeMonitorValue.getMonitorValue()) > 0 && Double.parseDouble(indicatorsVal.getMonitorValue()) > 0) {
                            Double monitorValue = Double.parseDouble(indicatorsVal.getMonitorValue());
                            Double lastMonitorValue = Double.parseDouble(lastTimeMonitorValue.getMonitorValue());
                            Double ringRatio = ((monitorValue - lastMonitorValue) / lastMonitorValue) * 100;
                            ringRatio = ringRatio > 100 ? 100 : ringRatio;
                            Double growthRatio = ((monitorValue - lastMonitorValue) / lastMonitorValue) * 100;
                            growthRatio = growthRatio > 100 ? 100 : growthRatio;
                            //保留后面两位小数
                            ringRatio = Double.parseDouble(ConvertUtil.formatNumber(ringRatio, 2));
                            growthRatio = Double.parseDouble(ConvertUtil.formatNumber(growthRatio, 2));
                            indicatorsVal.setRingRatio(ringRatio);
                            indicatorsVal.setGrowthRatio(growthRatio);
                            indicatorsVal.setMonitorRatio(growthRatio);
                        } else {
                            indicatorsVal.setRingRatio(0.0);
                            indicatorsVal.setGrowthRatio(0.0);
                            indicatorsVal.setMonitorRatio(0.0);
                        }
                    }
                    // 3.2版本特别，有自定义预警规则
                    indicatorsVal.setWarnStatus(updateWarnStatus(indicatorsVal));
                    // 判断是否填充0
                    String fillValue = null;
                    if (isFillZero) {
                        fillValue = "0";
                    }
                    indicatorsVal.setMonitorValue(StringUtils.isBlank(indicatorsVal.getMonitorValue()) ? fillValue : indicatorsVal.getMonitorValue());
                    indicatorsVal.setValue(StringUtils.isBlank(indicatorsVal.getValue()) ? fillValue : indicatorsVal.getValue());
                    indicatorsVal.setBaseValue(StringUtils.isBlank(indicatorsVal.getBaseValue()) ? fillValue : indicatorsVal.getBaseValue());
                    indicatorsVal.setTargetValue(StringUtils.isBlank(indicatorsVal.getTargetValue()) ? fillValue : indicatorsVal.getTargetValue());
                }
            }
            return valLinkedList;
        }).filter(idtval -> {
            return idtval != null && !idtval.isEmpty();
        }).collect(Collectors.toList());

        // 重新封装成列表
        List<ApiIndicatorsVal> resultList = new LinkedList<>();
        for (LinkedList<ApiIndicatorsVal> apiIndicatorsVals : collect) {
            resultList.addAll(apiIndicatorsVals);
        }
        return resultList;
    }

    /**
     * @描述: (新)查询指标数值，查询多指标多年份多行政区划
     * @入参: idtIds  必填，指标id列表
     * @入参: queryTimeBegin 查询时间字符串，年：2020；月：2020-01；季度：2020-1
     * @入参: queryTimeEnd 查询时间字符串，年：2020；月：2020-01；季度：2020-1
     * @入参: divisionCodes 必填，行政区划编码字符串，如果有多个，英文逗号隔开
     * @入参: isFillZero 必填，如果监测值/上报值/基期值/规划值不存在时，是否填充 0 ，true-填充，false-不填充
     * @入参: isReportValueForGrowthRatio 必填，是否使用上报值来计算增长率。true-使用上报值计算，false-使用监测值计算
     * @出参: List<ApiIndicatorsVal></ApiIndicatorsVal> 会查询指标的监测值、地区平均监测值、上报值、基期年、基期值、规划年、规划值、预警状态等基本数值字段。
     * @作者: 陈宏成
     * @日期: 2021-08-04
     **/
    public List<ApiIndicatorsVal> listIdtVal(List<String> idtIds, String queryTimeBegin, String queryTimeEnd, String divisionCodes, boolean isFillZero, boolean isReportValueForGrowthRatio) {
        // 将一个时间范围转成一个列表
        List<String> strings = DateUtil.fillTimeList(queryTimeBegin, queryTimeEnd);
        String queryTimeStr = String.join(",", strings);
        List<ApiIndicatorsVal> apiIndicatorsValList = this.listIdtVal(idtIds, queryTimeStr, divisionCodes, isFillZero, isReportValueForGrowthRatio);
        return apiIndicatorsValList;
    }

    /**
     * 根据规则获取监测值.
     *
     * @入参：idtId 指标id
     * @入参：divisionCode 行政区划编码
     * @入参：updateCycle 指标更新周期  ， year -- 年度更新，month -- 月度更新，quarter -- 季度更新
     * @入参：queryTime 查询时间  ， 2020 -- 年度，2021-09 -- 月度，2020-1 -- 季度
     * @入参：ruleType 规则类型  ， 1 -- monitor_time和更新周期一致 + monitor_time 和 queryTime 相等                                         <br/>
     * 2 -- updateCycle为年                                                                                  <br/>
     * -- queryTime 是年时： monitor_time长度为4位 + monitor_time 和 queryTime 相等                 <br/>
     * -- queryTime 是月/季时： monitor_time长度为4位 + monitor_time 和 queryTime的年度 相等          <br/>
     * -- updateCycle为季
     * -- queryTime 是年时： monitor_time长度为6位 + monitor_time最大 + 年份相等                      <br/>
     * -- queryTime 是季时： monitor_time长度为6位 + monitor_time 和 queryTime 相等                  <br/>
     * -- queryTime 是月时： monitor_time长度为6位 + monitor_time 和 queryTime所在的季 相等            <br/>
     * -- updateCycle为月
     * -- queryTime 是年时： monitor_time长度为7位 + monitor_time最大 + 年份相等                     <br/>
     * -- queryTime 是季时： monitor_time长度为7位 + monitor_time 和 queryTime季度所在的最大月 相等      <br/>
     * -- queryTime 是月时： monitor_time长度为7位 + monitor_time 和 queryTime 相等                  <br/>
     * @入参：monitorValueList 已经查询出来的监测值列表
     * @出参：
     * @作者： 陈宏成
     * @日期： 2021/10/27
     */
    private IdtMonitorValue getMonitorValue(String idtId, String divisionCode, String updateCycle, String queryTime, int ruleType, List<IdtMonitorValue> monitorValueList) {
        if (monitorValueList == null || monitorValueList.isEmpty()) {
            return null;
        }
        // 过滤出当前指标和行政区划的数据
        List<IdtMonitorValue> collect = monitorValueList.stream().filter(value -> {
            boolean b = Objects.equals(value.getIndicatorsId(), idtId) && Objects.equals(value.getDivisionCode(), divisionCode) && Objects.nonNull(value.getMonitorTime());
            return b;
        }).collect(Collectors.toList());
        if (collect.isEmpty()) {
            return null;
        }
        if (ruleType == 1) {
            // 1 -- monitor_time和更新周期一致 + monitor_time 和 queryTime 相等
            Optional<IdtMonitorValue> monitorValueOptional = collect.stream().filter(value -> {
                return value.getMonitorTime().length() == 4 && Objects.equals(value.getMonitorTime(), queryTime);
            }).findFirst();
            return monitorValueOptional.isPresent() ? monitorValueOptional.get() : null;
        } else if (ruleType == 2) {
            if (Objects.equals(updateCycle, "year")) {
                if (queryTime.length() == 4) {
                    // updateCycle为年，queryTime 是年时： monitor_time长度为4位 + monitor_time 和 queryTime 相等
                    Optional<IdtMonitorValue> monitorValueOptional = collect.stream().filter(value -> {
                        return value.getMonitorTime().length() == 4 && Objects.equals(value.getMonitorTime(), queryTime);
                    }).findFirst();
                    return monitorValueOptional.isPresent() ? monitorValueOptional.get() : null;
                } else {
                    // updateCycle为年，queryTime 是月/季时： monitor_time长度为4位 + monitor_time 和 queryTime的年度 相等
                    Optional<IdtMonitorValue> monitorValueOptional = collect.stream().filter(value -> {
                        return value.getMonitorTime().length() == 4 && Objects.equals(value.getMonitorTime(), queryTime.substring(0, 4));
                    }).findFirst();
                    return monitorValueOptional.isPresent() ? monitorValueOptional.get() : null;
                }
            } else if (Objects.equals(updateCycle, "quarter")) {
                if (queryTime.length() == 4) {
                    // updateCycle为季，queryTime 是年时： monitor_time长度为6位 + monitor_time最大
                    List<IdtMonitorValue> collect1 = collect.stream().filter(value -> {
                        return value.getMonitorTime().length() == 6 && Objects.equals(value.getMonitorTime().substring(0, 4), queryTime);
                    }).sorted(new Comparator<IdtMonitorValue>() {
                        @Override
                        public int compare(IdtMonitorValue o1, IdtMonitorValue o2) {
                            return o2.getMonitorTime().compareTo(o1.getMonitorTime());
                        }
                    }).collect(Collectors.toList());
                    return collect1 != null && !collect1.isEmpty() ? collect1.get(0) : null;
                } else if (queryTime.length() == 6) {
                    // updateCycle为季，queryTime 是季时：monitor_time长度为6位 + monitor_time 和 queryTime 相等
                    Optional<IdtMonitorValue> monitorValueOptional = collect.stream().filter(value -> {
                        return value.getMonitorTime().length() == 6 && Objects.equals(value.getMonitorTime(), queryTime);
                    }).findFirst();
                    return monitorValueOptional.isPresent() ? monitorValueOptional.get() : null;
                } else if (queryTime.length() == 7) {
                    // updateCycle为季，queryTime 是月时： monitor_time长度为6位 + monitor_time 和 queryTime所在的季 相等
                    int month = Integer.valueOf(queryTime.substring(5, 7));
                    int quarter = 0;
                    if (month <= 3 && month >= 1) {
                        quarter = 1;
                    } else if (month <= 6 && month >= 4) {
                        quarter = 2;
                    } else if (month <= 9 && month >= 7) {
                        quarter = 3;
                    } else if (month <= 12 && month >= 10) {
                        quarter = 4;
                    }
                    String quarterS = String.valueOf(quarter);
                    Optional<IdtMonitorValue> monitorValueOptional = collect.stream().filter(value -> {
                        return value.getMonitorTime().length() == 6 && Objects.equals(value.getMonitorTime(), queryTime.substring(0, 4) + "-" + quarterS);
                    }).findFirst();
                    return monitorValueOptional.isPresent() ? monitorValueOptional.get() : null;
                }
            } else if (Objects.equals(updateCycle, "month")) {
                if (queryTime.length() == 4) {
                    // updateCycle为月，queryTime 是年时： monitor_time长度为7位 + monitor_time最大
                    List<IdtMonitorValue> collect1 = collect.stream().filter(value -> {
                        return value.getMonitorTime().length() == 7 && Objects.equals(value.getMonitorTime().substring(0, 4), queryTime);
                    }).sorted(new Comparator<IdtMonitorValue>() {
                        @Override
                        public int compare(IdtMonitorValue o1, IdtMonitorValue o2) {
                            return o2.getMonitorTime().compareTo(o1.getMonitorTime());
                        }
                    }).collect(Collectors.toList());
                    return collect1 != null && !collect1.isEmpty() ? collect1.get(0) : null;
                } else if (queryTime.length() == 6) {
                    // updateCycle为月，queryTime 是季时： monitor_time长度为7位 + monitor_time 和 queryTime季度所在的最大月 相等
                    int quarter = Integer.valueOf(queryTime.substring(5, 6));
                    int monthBegin = 0;
                    int monthEnd = 0;
                    if (quarter == 1) {
                        monthBegin = 1;
                        monthEnd = 3;
                    } else if (quarter == 2) {
                        monthBegin = 4;
                        monthEnd = 6;
                    } else if (quarter == 3) {
                        monthBegin = 7;
                        monthEnd = 9;
                    } else if (quarter == 4) {
                        monthBegin = 10;
                        monthEnd = 12;
                    }
                    int monthBegin1 = monthBegin, monthEnd1 = monthEnd;
                    List<IdtMonitorValue> collect1 = collect.stream().filter((value) -> {
                        return value.getMonitorTime().length() == 7;
                    }).filter(value -> {
                        Integer month = Integer.valueOf(value.getMonitorTime().substring(5, 7));
                        return Objects.equals(value.getMonitorTime().substring(0, 4), queryTime.substring(0, 4)) && month >= monthBegin1 && month <= monthEnd1;
                    }).sorted(new Comparator<IdtMonitorValue>() {
                        @Override
                        public int compare(IdtMonitorValue o1, IdtMonitorValue o2) {
                            return o2.getMonitorTime().compareTo(o1.getMonitorTime());
                        }
                    }).collect(Collectors.toList());
                    return collect1 != null && !collect1.isEmpty() ? collect1.get(0) : null;
                } else if (queryTime.length() == 7) {
                    // updateCycle为月，queryTime 是月时： monitor_time长度为7位 + monitor_time 和 queryTime 相等
                    Optional<IdtMonitorValue> monitorValueOptional = collect.stream().filter(value -> {
                        return value.getMonitorTime().length() == 7 && Objects.equals(value.getMonitorTime(), queryTime);
                    }).findFirst();
                    return monitorValueOptional.isPresent() ? monitorValueOptional.get() : null;
                }
            }
        }
        return null;
    }

    /**
     * 判断是否存在同名指标
     *
     * @param idtName 指标名，不能为空
     * @param idtId   指标id，可以为空，如果不为空，将会比较同名的是不是自己
     * @return true -- 存在其他同名指标，false -- 不存在其他同名指标
     * @author 陈宏成
     * @date 2021/12/10
     */
    @Override
    public boolean hasName(String idtName, String idtId) {
        if (StringUtils.isBlank(idtName)) {
            throw new RuntimeException("指标名不能为空");
        }
        LambdaQueryWrapper<IdtIndicators> wrapper = new QueryWrapper().lambda();
        wrapper.eq(IdtIndicators::getName, idtName);
        wrapper.ne(StringUtils.isNotBlank(idtId), IdtIndicators::getId, idtId);
        List<IdtIndicators> indicatorsList = this.list(wrapper);
        if (indicatorsList != null && !indicatorsList.isEmpty()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取非复合指标列表，不分页 <br/><br/><br/>
     * 2021-12-21 为了避免指标计算公式出现A=B+C，C=E+D这种链式的情况，所有复合指标禁止作为计算公式的因子 <br/><br/>
     * 同样的因子可以被引用多次到公式，只是因子不能再被配公式 <br/><br/>
     * 有可能一个因子b是模型算的，一个因子c是系统对接的，指标a=b+c就是自动算的<br/><br/>
     *
     * @param excludeIdList 要排除的指标id列表，可以为空
     * @author 陈宏成
     * @date 2021/12/21
     */
    @Override
    public List<IdtIndicators> listNonCompositeIdts(List<String> excludeIdList) {
        // id not in (#{excludeIdList})
        LambdaQueryWrapper<IdtIndicators> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.notIn(!CollectionUtils.isEmpty(excludeIdList), IdtIndicators::getId, excludeIdList);
        queryWrapper.and(new Consumer<LambdaQueryWrapper<IdtIndicators>>() {
            @Override
            public void accept(LambdaQueryWrapper<IdtIndicators> queryWrapper1) {
                //and (calculate_result is null or calculate_result = '')
                queryWrapper1.isNull(IdtIndicators::getCalculateResult);
                queryWrapper1.or();
                queryWrapper1.eq(IdtIndicators::getCalculateResult, "");
            }
        });

        List<IdtIndicators> list = this.list(queryWrapper);
        return list;
    }

    /**
     * 根据指标，查询相关联的复合指标
     *
     * @param idtId   指标id，idtId 和 idtCode 二选一，如果都存在，默认idtId
     * @param idtCode 指标编码，idtId 和 idtCode 二选一，如果都存在，默认idtId
     * @return 例如存在指标计算公式 A=B+C ; E=B+F ，（B）--> A、E
     * @author 陈宏成
     * @date 2021/12/21
     */
    @Override
    public List<IdtIndicators> findCompositeIdts(String idtId, String idtCode) {
        if (StringUtils.isBlank(idtId) && StringUtils.isBlank(idtCode)) {
            throw new RuntimeException("参数 idtId 和 idtCode 不能都为空");
        }
        LambdaQueryWrapper<IdtIndicators> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(idtId)) {
            queryWrapper.eq(IdtIndicators::getId, idtId);
        } else {
            queryWrapper.eq(IdtIndicators::getCode, idtCode);
        }
        // 获取当前指标
        IdtIndicators indicator = this.getOne(queryWrapper);
        if (Objects.isNull(indicator)) {
            throw new RuntimeException(String.format("idtId：%s，idtCode：%s，指标不存在", idtId, idtCode));
        }
        // 根据该指标查询对应的复合指标
        queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(IdtIndicators::getDatasource, IDT_DATASOURCE_FORMULA);
        queryWrapper.like(IdtIndicators::getCalculateResult, indicator.getCode());
        List<IdtIndicators> list = this.list(queryWrapper);
        return list;
    }

    @Override
    public List<PageData> listDivisionByEntity(PageData pd) {
        return idtIndicatorsMapper.listDivisionByEntity(pd);
    }

    @Override
    public List<ApiIndicatorsVal> mapIdtVal3(List<ApiIdtIndicatorsDir> treeList, String year, MapDivision divisionCode, List<ApiIdtIndicatorsDir> dirs, List<String> ids) {
        List<String> idtIds = treeList.stream().filter(idtDir -> {
            return idtDir.getType() == 2;
        }).map(ApiIdtIndicatorsDir::getIndicatorsId).collect(Collectors.toList());

        //监测值
        LambdaQueryWrapper<IdtMonitorValue> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.in(IdtMonitorValue::getIndicatorsId, idtIds);
        wrapper1.eq(IdtMonitorValue::getYear, Integer.valueOf(year));
        wrapper1.eq(IdtMonitorValue::getDivisionCode, divisionCode.getCode());
        List<IdtMonitorValue> monitorValueList = iIdtMonitorValueService.list(wrapper1);

        // 查询指标对标关系
        LambdaQueryWrapper<IdtYearRelevance> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.in(IdtYearRelevance::getIndicatorsId, idtIds);
        List<IdtYearRelevance> yearRelevanceList = this.iIdtYearRelevanceService.list(wrapper2);

        // 查询规划值数据
        LambdaQueryWrapper<IdtTargetValue> wrapper3 = new LambdaQueryWrapper<>();
        wrapper3.in(IdtTargetValue::getIndicatorsId, idtIds);
        wrapper3.eq(IdtTargetValue::getDivisionCode, divisionCode.getCode());
        List<IdtTargetValue> targetValueList = this.iIdtTargetValueService.list(wrapper3);

        // 根据指标id分组
        Map<String, List<IdtMonitorValue>> monitorValueMap = monitorValueList.stream().collect(Collectors.groupingBy(IdtMonitorValue::getIndicatorsId));
        // 根据指标id分组
        Map<String, List<IdtYearRelevance>> yearRelevanceMap = yearRelevanceList.stream().collect(Collectors.groupingBy(IdtYearRelevance::getIndicatorsId));
        // 根据指标id分组
        Map<String, List<IdtTargetValue>> targetValueMap = targetValueList.stream().collect(Collectors.groupingBy(IdtTargetValue::getIndicatorsId));

        List<ApiIndicatorsVal> resultList = new ArrayList<>();
        for (ApiIdtIndicatorsDir idtIndicator : treeList) {
            if (idtIndicator.getType() == 2) {
                String idtId = idtIndicator.getIndicatorsId();

                //标识合并
                if (!ids.contains(idtId)) {
                    dirs.add(idtIndicator);
                    ids.add(idtId);
                }

                // 各个行政区的监测值
                List<IdtMonitorValue> monitorValueList1 = monitorValueMap.get(idtId);
                // 各个行政区的监测值map
                Map<String, IdtMonitorValue> monitorValueMapCode = new HashMap<>();
                if (monitorValueList1 != null && !monitorValueList1.isEmpty()) {
                    monitorValueMapCode = monitorValueList1.stream().collect(Collectors.toMap(e -> e.getDivisionCode(), e -> e, (e1, e2) -> e2));
                }


                ApiIndicatorsVal baseVal = new ApiIndicatorsVal();
                baseVal.setId(idtIndicator.getIndicatorsId());
                baseVal.setUnit(idtIndicator.getIdtUnit());
                baseVal.setName(idtIndicator.getName());
                baseVal.setConnotation(idtIndicator.getIdtConnotation());
                baseVal.setAttribute(idtIndicator.getIdtAttribute());
                baseVal.setCode(idtIndicator.getIdtCode());
                baseVal.setGatherCompany(idtIndicator.getIdtGatherCompany());
                baseVal.setDutyCompany(idtIndicator.getIdtDutyCompany());
                baseVal.setDutyDepartment(idtIndicator.getIdtDutyDepartment());
                baseVal.setCalculateUnit(idtIndicator.getIdtCalculateUnit());
                baseVal.setUpdateCycle(idtIndicator.getIdtUpdateCycle());
                baseVal.setWarnRuleConfig(idtIndicator.getWarnRuleConfig());
                baseVal.setEstimateRuleConfig(idtIndicator.getEstimateRuleConfig());

                // 行政区划
                baseVal.setDivisionCode(divisionCode.getCode());
                baseVal.setDivisionName(divisionCode.getName());

                // 查询时间，查询年份
                baseVal.setQueryTime(year);
                baseVal.setQueryYear(year);

                //当前指标、当前行政区的监测值
                IdtMonitorValue monitorValue1 = monitorValueMapCode.get(divisionCode.getCode());
                if (monitorValue1 != null) {
                    baseVal.setMonitorValue(monitorValue1.getMonitorValue());
                    baseVal.setMonitorYear(monitorValue1.getYear().toString());
                    baseVal.setMonitorTime(monitorValue1.getMonitorTime());
                    baseVal.setUpdateDate(monitorValue1.getModifyTime());
                    baseVal.setWarnStatus(monitorValue1.getWarnStatus());
                }

                //规划值，先查对标关系，再查规划值
                List<IdtYearRelevance> yearRelevanceList1 = yearRelevanceMap.get(idtId);
                if (yearRelevanceList1 != null && !yearRelevanceList1.isEmpty()) {
                    Integer queryYear = Integer.valueOf(baseVal.getQueryYear());
                    Optional<IdtYearRelevance> yearRelevanceOptional = yearRelevanceList1.stream().filter(yearRelevance -> {
                        Integer startYear = Integer.valueOf(yearRelevance.getMonitorReportYear().substring(0, 4));
                        Integer endYear = Integer.valueOf(yearRelevance.getMonitorReportYear().substring(5, 9));
                        if (queryYear <= endYear && queryYear >= startYear) {
                            return true;
                        }
                        return false;
                    }).findFirst();
                    if (yearRelevanceOptional.isPresent()) {
                        // 查规划值
                        List<IdtTargetValue> targetValueList1 = targetValueMap.get(idtId);
                        if (targetValueList1 != null && !targetValueList1.isEmpty()) {
                            Optional<IdtTargetValue> targetValueOptional = targetValueList1.stream().filter(targetValue -> {
                                // 行政区划一致 + 规划值规划年和对标关系规划年一致
                                if (Objects.equals(targetValue.getDivisionCode(), divisionCode.getCode()) && targetValue.getTargetYear().intValue() == yearRelevanceOptional.get().getPlanTargetYear().intValue()) {
                                    return true;
                                }
                                return false;
                            }).findFirst();
                            if (targetValueOptional.isPresent()) {
                                baseVal.setBaseYear(targetValueOptional.get().getBaseYear());
                                baseVal.setBaseValue(targetValueOptional.get().getBaseValue());
                                baseVal.setTargetYear(targetValueOptional.get().getTargetYear().toString());
                                baseVal.setTargetValue(targetValueOptional.get().getTargetValue());
                                baseVal.setTargetExplain(targetValueOptional.get().getExplain());
                            }
                        }
                    }
                }

                // 填充0
//                String fillValue = "0";
//                baseVal.setMonitorValue(StringUtils.isBlank(baseVal.getMonitorValue()) ? fillValue : baseVal.getMonitorValue());
//                baseVal.setValue(StringUtils.isBlank(baseVal.getValue()) ? fillValue : baseVal.getValue());
//                baseVal.setBaseValue(StringUtils.isBlank(baseVal.getBaseValue()) ? fillValue : baseVal.getBaseValue());
//                baseVal.setTargetValue(StringUtils.isBlank(baseVal.getTargetValue()) ? fillValue : baseVal.getTargetValue());
                resultList.add(baseVal);
            }
        }
        return resultList;
    }
}
